﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace MoneyWentWhere.DataModel.Storage
{
    public abstract class DataFormatX
    {
        public static DataFormatX MwwXml = new NativeXmlFormat();
        public static DataFormatX EncryptedMwwXml = new EncryptedFormat(MwwXml);
        public static DataFormatX Excel2007 = new Excel2007Format();

        public virtual void Save(MoneyDataSet ds, String filename)
        {
            ds.Filename = filename;
            ds.DataFormat = this;
            using (FileStream s = new FileStream(filename, FileMode.Create))
            {
                Save(ds, s);
            }
        }

        public virtual MoneyDataSet Load(String filename)
        {
            MoneyDataSet ds = new MoneyDataSet();
            using (FileStream s = new FileStream(filename, FileMode.Open))
            {
                ds = Load(s);
            }
            ds.Filename = filename;
            ds.DataFormat = this;
            if (this is IHasPassword)
            {
                ds.Password = ((IHasPassword)this).Password;
            }
            return ds;
        }

        public abstract void Save(MoneyDataSet ds, Stream outStream);
        public abstract MoneyDataSet Load(Stream inStream);

        // TODO: Add support to merge into existing dataSet (for copy & paste)
        // This might require some extra context (e.g. where is data pasted)

        /// <summary>
        /// Get the data format based on the type.
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        public static DataFormatX GetFormat(String filename)
        {
            DataFormatX[] AcceptedFormats = new DataFormatX[] 
                { EncryptedMwwXml, MwwXml, Excel2007 };

            foreach (DataFormatX f in AcceptedFormats)
            {
                if (f.AcceptsFile(filename))
                {
                    return f;
                }
            }
            // No format accepted
            return null;
        }

        public abstract bool AcceptsFile(String filename);

    }
}
